home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Education
/
World of Education.iso
/
world_p
/
pcshx10b.zip
/
PCSHX10B.EXE
/
GNUFGREP.EXE
/
GREPDOCS.EXE
/
GLOBARGV.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-31
|
4KB
|
161 lines
/*-
* int globargv(&argc, &argv, globber)
*
* General purpose globbing routine for argv lists. You can call
* globargv() near the beginning of a main program to glob the program
* argument list. The new argv list will be dynamically allocated
* and NULL terminated.
*
* `globber' is a function declared as `char **globber(char *pattern)',
* and should behave the way GNU glob_filename() does. That is as follows:
* -- If there is a memory allocation overflow, return NULL
* -- If there is a file access error (ENOENT, for instance),
* return (char **) -1 [globargv() considers a file access
* error to be equivalent to a `no match']
* -- If there is no match, return a pointer to a NULL pointer
* -- Otherwise, return a pointer to a NULL terminated array of
* pointers to the globbing matches
*
* Note that globargv() runs an in-place sort on the array returned by
* globber(). I think this is unlikely to be a problem.
*
* The return value of globargv() is -1 if a memory allocation error
* occurred, otherwise 0. Only in the latter case are argc and argv
* affected.
*
* Written by Barry Schwartz, 29 August 1990.
*/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <search.h>
/* Comparison function for qsort() */
static int
arg_compare(const char **arg1, const char **arg2)
{
/* Use the Microsoft library stricmp() function, which is a case
* insensitive version of strcmp */
return stricmp(*arg1, *arg2);
}
/*-
* 0 --> success
* -1 --> memory allocation overflow
*/
int
globargv(int *argc, char ***argv, char **(*globber)(char *))
{
char **p;
char **newargv;
char **globber_output;
unsigned int number_of_new_args;
int newargc;
int oldarg_index;
newargv = malloc(2 * sizeof(char *));
if (!newargv)
goto cannot_allocate;
newargv[0] = (*argv)[0]; /* Program name */
newargv[1] = NULL;
newargc = 1;
for (oldarg_index = 1; oldarg_index != *argc; ++oldarg_index)
{
globber_output = (*globber)((*argv)[oldarg_index]);
if (globber_output == NULL)
goto cannot_allocate;
/* Count the number of new arguments (zero if no match or
* file error occurred) */
number_of_new_args = 0;
if (globber_output != (char **) -1)
for (p = globber_output; *p; ++p)
++number_of_new_args;
/* Sort the globber output in case-insensitive ascending
* ASCII order */
if (number_of_new_args > 1)
qsort(globber_output, number_of_new_args,
sizeof(globber_output[0]), arg_compare);
/* Incorporate the new arguments into the new argv list */
if (number_of_new_args == 0)
{
newargv = realloc(newargv, (newargc + 2) * sizeof(char *));
if (!newargv)
goto cannot_allocate;
newargv[newargc++] = (*argv)[oldarg_index];
newargv[newargc] = NULL;
}
else
{
newargv = realloc(newargv,
(newargc + number_of_new_args + 1) * sizeof(char *));
if (!newargv)
goto cannot_allocate;
for (p = globber_output; *p; ++p)
newargv[newargc++] = *p;
newargv[newargc] = NULL;
}
}
/* Successful return */
*argv = newargv;
*argc = newargc;
return 0;
cannot_allocate:
/* Error occurred while allocating memory. Any blocks already
* allocated should have been freed (by realloc()) when the error
* occurred. */
return -1;
}
#ifdef TEST
#include <stdio.h>
int
main(int argc, char **argv)
{
extern int backslash_same_as_slash;
char **glob_filename(char *);
backslash_same_as_slash = 1;
switch (globargv(&argc, &argv, glob_filename))
{
case -1:
fprintf(stderr, "memory allocation error, return value -1\n");
return -1;
case 0:
{
int i;
for (i = 0; i != argc; ++i)
printf("%s ", argv[i]);
}
putchar('\n');
if (argv[argc] != NULL)
fprintf(stderr, "argv[argc] is not NULL\n");
return 0;
default:
fprintf(stderr, "illegal return value\n");
return 1;
}
}
#endif